package org.unidata.mdm.meta.dao.impl;

import java.util.List;
import java.util.Properties;

import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;
import org.unidata.mdm.meta.dao.SourceSystemsDAO;
import org.unidata.mdm.meta.po.AbstractModelPO;
import org.unidata.mdm.meta.po.SourceSystemsPO;
import org.unidata.mdm.system.dao.impl.BaseDAOImpl;

/**
 * @author Mikhail Mikhailov on Oct 1, 2020
 * Source systems CRUD.
 */
@Repository
public class SourceSystemsDAOImpl extends BaseDAOImpl implements SourceSystemsDAO {
    /**
     * Default SSPO row mapper.
     */
    private static final RowMapper<SourceSystemsPO> DEFAULT_ROW_MAPPER = (rs, row) -> {

        SourceSystemsPO result = new SourceSystemsPO();
        result.setStorageId(rs.getString(AbstractModelPO.FIELD_STORAGE_ID));
        result.setRevision(rs.getInt(AbstractModelPO.FIELD_REVISION));
        result.setOperationId(rs.getString(AbstractModelPO.FIELD_OPERATION_ID));
        result.setDescription(rs.getString(AbstractModelPO.FIELD_DESCRIPTION));
        result.setCreatedBy(rs.getString(AbstractModelPO.FIELD_CREATED_BY));
        result.setCreateDate(rs.getTimestamp(AbstractModelPO.FIELD_CREATE_DATE));
        result.setContent(rs.getBytes(AbstractModelPO.FIELD_CONTENT));

        return result;
    };
    /**
     * Queries.
     */
    private final String currentSQL;
    private final String loadSQL;
    private final String saveSQL;
    private final String removeSQL;
    /**
     * Constructor.
     */
    @Autowired
    public SourceSystemsDAOImpl(
            @Qualifier("metaDataSource") final DataSource dataSource,
            @Qualifier("source-systems-model-sql") final Properties sql) {
        super(dataSource);
        currentSQL = sql.getProperty("currentSQL");
        loadSQL = sql.getProperty("loadSQL");
        saveSQL = sql.getProperty("saveSQL");
        removeSQL = sql.getProperty("removeSQL");
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public SourceSystemsPO current(String storageId) {
        return getJdbcTemplate().query(currentSQL, rs -> rs.next() ? DEFAULT_ROW_MAPPER.mapRow(rs, 0) : null, storageId);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public List<SourceSystemsPO> load(String storageId, int from, int count, boolean withData) {
        return getJdbcTemplate().query(loadSQL, DEFAULT_ROW_MAPPER, withData, storageId, from, count);
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public int save(SourceSystemsPO po) {
        return getJdbcTemplate().queryForObject(saveSQL, Integer.class,
                po.getStorageId(),
                po.getRevision(),
                po.getDescription(),
                po.getOperationId(),
                po.getContent(),
                po.getCreatedBy());
    }
    /**
     * {@inheritDoc}
     */
    @Override
    public void remove(String storageId, int revision) {
        getJdbcTemplate().update(removeSQL, storageId, revision);
    }
}
